package com.ruoyi.mes.service.impl;

import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.mes.domain.*;
import com.ruoyi.mes.mapper.*;
import com.ruoyi.mes.utils.AgvUtils;
import com.ruoyi.mes.utils.LongMenUtils;
import com.ruoyi.mes.utils.QualityInspectionUtils;
import com.ruoyi.mes.vo.product.ProStockInhouVo;
import com.ruoyi.mes.vo.qualityinspection.QualityInspectionVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ruoyi.mes.service.IFinishInhouService;
import org.springframework.transaction.annotation.Transactional;

/**
 * 完工入库Service业务层处理
 *
 * @author LongAndHao
 * @date 2023-05-17
 */
@Service
public class FinishInhouServiceImpl implements IFinishInhouService {
    @Autowired
    private HouInfoMapper houInfoMapper;

    @Autowired
    private ProStockMapper proStockMapper;

    @Autowired
    private ProInfoMapper proInfoMapper;

    @Autowired
    private FinishInhouMapper finishInhouMapper;

    @Autowired
    private LocatorInfoMapper locatorInfoMapper;
    @Autowired
    private WkspTaskMapper wkspTaskMapper;
    @Autowired
    private ProgPlanDetailMapper progPlanDetailMapper;
    @Autowired
    private ProductionLineMapper productionLineMapper;;
    /**
     * 查询完工入库
     *
     * @param id 完工入库主键
     * @return 完工入库
     */
    @Override
    public FinishInhou selectFinishInhouById(Long id) {
        return finishInhouMapper.selectFinishInhouById(id);
    }

    /**
     * 查询完工入库列表
     *
     * @param finishInhou 完工入库
     * @return 完工入库
     */
    @Override
    public List<FinishInhou> selectFinishInhouList(FinishInhou finishInhou) {
        List<FinishInhou> finishInhous = finishInhouMapper.selectFinishInhouList(finishInhou);
        //处理返回产品信息
        if (finishInhous.size() != 0) {
            for (FinishInhou inhous : finishInhous) {
                ProInfo proInfo = proInfoMapper.selectProInfoById(inhous.getProId());
                inhous.setProCode(proInfo.getProCode());
                inhous.setProName(proInfo.getProName());
            }
        }
        return finishInhous;
    }

    /**
     * 新增完工入库
     *
     * @param finishInhou 完工入库
     * @return 结果
     */
    @Override
    public int insertFinishInhou(FinishInhou finishInhou) {
        finishInhou.setCreateTime(DateUtils.getNowDate());
        return finishInhouMapper.insertFinishInhou(finishInhou);
    }

    /**
     * 修改完工入库
     *
     * @param finishInhou 完工入库
     * @return 结果
     */
    @Override
    public int updateFinishInhou(FinishInhou finishInhou) {
        finishInhou.setUpdateTime(DateUtils.getNowDate());
        return finishInhouMapper.updateFinishInhou(finishInhou);
    }

    /**
     * 批量删除完工入库
     *
     * @param ids 需要删除的完工入库主键
     * @return 结果
     */
    @Override
    public int deleteFinishInhouByIds(Long[] ids) {
        return finishInhouMapper.deleteFinishInhouByIds(ids);
    }

    /**
     * 删除完工入库信息
     *
     * @param id 完工入库主键
     * @return 结果
     */
    @Override
    public int deleteFinishInhouById(Long id) {
        return finishInhouMapper.deleteFinishInhouById(id);
    }


    /**
     * 入库
     * @param proStockInhouVo
     * @return
     */
    @Override
    @Transactional
    public AjaxResult inHou(ProStockInhouVo proStockInhouVo) {
        FinishInhou finishInhou = finishInhouMapper.selectFinishInhouById(proStockInhouVo.getId());//入库记录
        ProInfo proInfo = proInfoMapper.selectProInfoById(finishInhou.getProId());//产品信息


        //判断库房剩余容量是否充足
        HouInfo houInfo = houInfoMapper.selectHouInfoByHouId(proStockInhouVo.getHouId());
        if ( houInfo.getHouRemainCapacity() < finishInhou.getInhouQuantity()) {
            return AjaxResult.error("库存剩余容量不足!");
        }

        //更新库位
        LocatorInfo locatorInfo = locatorInfoMapper.selectLocatorInfoById(proStockInhouVo.getLocatorInfoId());
        if (locatorInfo.getSerialCode() == null || StringUtils.isBlank(locatorInfo.getSerialCode())){//空库位
            locatorInfo.setSerialCode(proInfo.getProCode());
        } else if (!locatorInfo.getSerialCode().equals(proInfo.getProCode())) {
            return AjaxResult.error("物品不匹配!");
        }

//        //调取龙门,根据库位进行放料
//        LongMenUtils.LongMenPutWithLocator(proStockInhouVo.getLocatorInfoId());

        //更新库房剩余容量
        houInfo.setHouRemainCapacity(houInfo.getHouRemainCapacity() - finishInhou.getQualifiedNum());
        houInfoMapper.updateHouInfo(houInfo);


        locatorInfo.setRemainCapacity(locatorInfo.getRemainCapacity() - finishInhou.getQualifiedNum());
        locatorInfoMapper.updateLocatorInfo(locatorInfo);

        //更新产品库存
        ProStock proStock = proStockMapper.selectMtrStockByMtrCode(proStockInhouVo.getHouId(), proInfo.getProCode());

        if (proStock == null) {//若产品库存没有存放过该产品，则新增
            ProStock stock = new ProStock();
            stock.setHouId(proStockInhouVo.getHouId());
            stock.setProCode(proInfo.getProCode());
            stock.setProName(proInfo.getProName());
            stock.setProType(proInfo.getProType());
            stock.setProQuantity(finishInhou.getQualifiedNum());
            proStockMapper.insertProStock(stock);

        } else {
            //更新产品库存
            proStock.setProQuantity(proStock.getProQuantity() + finishInhou.getQualifiedNum());
            proStockMapper.updateProStock(proStock);
        }
        //更新入库状态
        finishInhou.setStatus(1L);
        finishInhou.setInhouName(SecurityUtils.getLoginUser().getUser().getNickName());
        finishInhou.setInhouTime(proStockInhouVo.getInhouTime());
        finishInhouMapper.updateFinishInhou(finishInhou);

        return AjaxResult.success("入库成功!");
    }

    /**
     * 质检
     * @param id 完工入库id
     * @return
     */
    @Override
    @Transactional
    public AjaxResult qualityInspection(Long id) throws IOException {
       QualityInspectionVo qualityInspectionVo = new QualityInspectionVo();
        FinishInhou finishInhou = finishInhouMapper.selectFinishInhouById(id);
        WkspTask wkspTask = wkspTaskMapper.selectWkspTaskById(finishInhou.getWkspTaskId());
        ProgPlanDetail progPlanDetail = progPlanDetailMapper.selectProgPlanDetailById(wkspTask.getProgDetailId());
        ProductionLine productionLine = productionLineMapper.selectProductionLineByLineId(progPlanDetail.getLineId());
        if (productionLine.getLineType().equals("1")) {
            //判断质检是否通过
//       QualityInspectionVo qualityInspectionVo = QualityInspectionUtils.qualityInspection();
            //测试用

            qualityInspectionVo.setIs_pass(true);

//        ***********************
            if (!qualityInspectionVo.getIs_pass()) {
                AgvUtils.dispatchAgv();

                ScheduledExecutorService executorService = Executors.newSingleThreadScheduledExecutor();
                executorService.schedule(() -> {
                    // 等待24秒后执行以下代码
                    LongMenUtils.LongMenPutWithLocator(18L);
                    // 更新库位、库房剩余容量及完工入库信息
                    LocatorInfo locatorInfo = locatorInfoMapper.selectLocatorInfoById(18L);
                    locatorInfo.setRemainCapacity(locatorInfo.getRemainCapacity() - 1);

                    HouInfo houInfo = houInfoMapper.selectHouInfoByHouId(locatorInfo.getHouId());
                    houInfo.setHouRemainCapacity(houInfo.getHouRemainCapacity() - 1);

                    finishInhou.setStatus(1L);
                    houInfoMapper.updateHouInfo(houInfo);
                    locatorInfoMapper.updateLocatorInfo(locatorInfo);
                    finishInhouMapper.updateFinishInhou(finishInhou);
                }, 24, TimeUnit.SECONDS);

                return AjaxResult.success("质检未通过!", qualityInspectionVo);
            }
//        if (qualityInspectionVo.getIs_pass() == false){
//            AvgUtils.DispatchAvg();
//            try {
//                Thread.sleep(1000 * 24);
//            } catch (InterruptedException e) {
//                throw new RuntimeException(e);
//            }
//
//            LongMenUtils.LongMenPutWithLocator(18L);
//            //更新库位、库房剩余容量及完工入库信息
//            LocatorInfo locatorInfo = locatorInfoMapper.selectLocatorInfoById(18L);
//            locatorInfo.setRemainCapacity(locatorInfo.getRemainCapacity() - 1);
//
//            HouInfo houInfo = houInfoMapper.selectHouInfoByHouId(locatorInfo.getHouId());
//            houInfo.setHouRemainCapacity(houInfo.getHouRemainCapacity() -1);
//
//            finishInhou.setStatus(1L);
//            houInfoMapper.updateHouInfo(houInfo);
//            locatorInfoMapper.updateLocatorInfo(locatorInfo);
//            finishInhouMapper.updateFinishInhou(finishInhou);
//
//            return AjaxResult.success("质检未通过!",qualityInspectionVo);
//        }

        }
        // 如果是虚拟产线（例如生产线类型为"0"），可以走模拟质检流程
        if (productionLine.getLineType().equals("0")) {
            Long totalQuantity = finishInhou.getInhouQuantity();
            int qualifiedCount = 0;
            int unqualifiedCount = 0;
            // 为不合格产品入库安排定时任务（这里统一创建一个调度器，避免每次创建一个新的）
            ScheduledExecutorService scheduledExecutor = Executors.newSingleThreadScheduledExecutor();

            // 遍历每一个产品
            for (int i = 0; i < totalQuantity; i++) {
                // 模拟质检过程，每个产品都有独立的质检时间（通过 sleep 模拟）
                QualityInspectionVo inspectionResult = simulateVirtualLineInspection();

                if (inspectionResult.getIs_pass()) {
                    // 质检通过，将产品入“合格产品库”
                    qualifiedCount++;
                    putProductIntoQualifiedWarehouse();
                } else {
                    // 质检不通过，将产品入“不合格产品库”
                    unqualifiedCount++;
                    // 如果需要延时执行，比如等待4秒后执行不合格产品入库操作
                    scheduledExecutor.schedule(() -> {
                        putProductIntoUnqualifiedWarehouse();
                    }, 4, TimeUnit.SECONDS);
                }
            }

            // 更新入库记录中合格产品的数量
            finishInhou.setStatus(1L);
            finishInhouMapper.updateFinishInhou(finishInhou);

            // 关闭调度器（注意：如果还有后续任务或需要长时间运行，可考虑延迟关闭）
            scheduledExecutor.shutdown();
            // 构造返回数据
            Map<String, Object> resultData = new HashMap<>();
            resultData.put("qualifiedCount", qualifiedCount);
            resultData.put("unqualifiedCount", unqualifiedCount);

            return AjaxResult.success("虚拟产线质检完成",resultData);
        } else {
            // 如果不是虚拟产线，则可以按照实际逻辑处理
            // 此处仅作为示例，直接返回成功提示
            return AjaxResult.success("非虚拟产线，请走正常的质检流程！");
        }
    }

    /**
     * 模拟质检过程，每个产品的质检结果有80%的概率通过，
     * 同时根据结果 sleep 不同的时长（通过：37秒，未通过：41秒），用于模拟质检时间
     */
    private QualityInspectionVo simulateVirtualLineInspection() {
        Random random = new Random();
        boolean isPass = random.nextInt(100) < 80; // 80%概率通过
        QualityInspectionVo qualityInspectionVo = new QualityInspectionVo();
        qualityInspectionVo.setIs_pass(isPass);

        try {
            if (isPass) {
                Thread.sleep(37 * 10L);  // 质检通过，模拟等待37秒（注意 sleep 参数单位为毫秒）
            } else {
                Thread.sleep(41 * 10L);  // 质检未通过，模拟等待41秒
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        return qualityInspectionVo;
    }

    /**
     * 将产品放入合格产品库
     */
    private void putProductIntoQualifiedWarehouse() {
        // 假设合格产品库使用库位ID为17
        Long qualifiedLocatorId = 17L;
        // 执行入库操作（调用工具类方法）

        // 更新库位信息：减少剩余容量
        LocatorInfo locatorInfo = locatorInfoMapper.selectLocatorInfoById(qualifiedLocatorId);
        locatorInfo.setRemainCapacity(locatorInfo.getRemainCapacity() - 1);
        locatorInfoMapper.updateLocatorInfo(locatorInfo);

        // 更新仓库信息：减少仓库剩余容量
        HouInfo houInfo = houInfoMapper.selectHouInfoByHouId(locatorInfo.getHouId());
        houInfo.setHouRemainCapacity(houInfo.getHouRemainCapacity() - 1);
        houInfoMapper.updateHouInfo(houInfo);
    }

    /**
     * 将产品放入不合格产品库
     */
    private void putProductIntoUnqualifiedWarehouse() {
        // 假设不合格产品库使用库位ID为18
        Long unqualifiedLocatorId = 18L;

        // 更新库位信息：减少剩余容量
        LocatorInfo locatorInfo = locatorInfoMapper.selectLocatorInfoById(unqualifiedLocatorId);
        locatorInfo.setRemainCapacity(locatorInfo.getRemainCapacity() - 1);
        locatorInfoMapper.updateLocatorInfo(locatorInfo);

        // 更新仓库信息：减少仓库剩余容量
        HouInfo houInfo = houInfoMapper.selectHouInfoByHouId(locatorInfo.getHouId());
        houInfo.setHouRemainCapacity(houInfo.getHouRemainCapacity() - 1);
        houInfoMapper.updateHouInfo(houInfo);
    }
}
